/*
 * Copyright (c) 2010-2013 Ruben Chakhmakhchyan. All rights reserved.
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Eclipse Public License
 * Version 1.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://opensource.org/licenses/EPL-1.0 and read it before using this file.
 */

#pragma once

template<class T>
class CProxy_IScriptableControlEvents :
	public IConnectionPointImpl<T, &__uuidof(_IScriptableControlEvents)>
{
public:

	HRESULT invoke( DISPID dispId )
	{
		HRESULT hr = S_OK;
		T* pThis = static_cast<T*>(this);
		int count = m_vec.GetSize();

		for ( int i = 0; i < count; i++ )
		{
			//pThis->Lock();
			IUnknown* punkConnection = m_vec.GetAt( i );
			//pThis->Unlock();

			IDispatch* pConnection = static_cast<IDispatch*>( punkConnection );

			if ( pConnection )
			{
				VARIANT varResult = { 0 };

				DISPPARAMS params = { NULL, NULL, 0, 0 };

				hr = pConnection->Invoke( dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL );
			}
		}
		return hr;
	}

	HRESULT invoke( DISPID dispId, int arg0 )
	{
		HRESULT hr = S_OK;
		T * pThis = static_cast<T*>( this );
		int count = m_vec.GetSize();

		for ( int i = 0; i < count; i++ )
		{
			//pThis->Lock();
			IUnknown* punkConnection = m_vec.GetAt( i );
			//pThis->Unlock();

			IDispatch* pConnection = static_cast<IDispatch*>( punkConnection );

			VARIANT varParam = { 0 };

			if ( pConnection )
			{
				VARIANT varResult = { 0 };
				//VariantClear( &varResult );

				varParam.vt = VT_INT;
				varParam.intVal = arg0;

				DISPPARAMS params = { &varParam, NULL, 1, 0 };

				hr = pConnection->Invoke( dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL );
			}
		}
		return hr;
	}

	HRESULT invoke( DISPID dispId, int arg0, int arg1 )
	{
		HRESULT hr = S_OK;
		T* pThis = static_cast<T*>( this );
		int count = m_vec.GetSize();

		for ( int i = 0; i < count; i++ )
		{
			//pThis->Lock();
			IUnknown* punkConnection = m_vec.GetAt( i );
			//pThis->Unlock();

			IDispatch* pConnection = static_cast<IDispatch*>( punkConnection );

			if ( pConnection )
			{
				VARIANT varResult = { 0 };
				//VariantClear(&varResult);

				VARIANT pvars[ 2 ] = { 0 };

				pvars[ 0 ].vt = VT_INT;
				pvars[ 0 ].intVal = arg1;

				pvars[ 1 ].vt = VT_INT;
				pvars[ 1 ].intVal = arg0;

				DISPPARAMS params = { pvars, NULL, 2, 0 };

				hr = pConnection->Invoke( dispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL );
			}
		}
		return hr;
	}

	HRESULT Fire_onUploadComplete( int uploadId, int resultCode )
	{
		return invoke( 2, uploadId, resultCode );
	}

	/*HRESULT Fire_onUploadFailed( int uploadId, int resultCode )
	{
		return invoke( 6, uploadId, resultCode );
	}*/

	HRESULT Fire_onScanComplete( int numberOfPages )
	{
		return invoke( 1, numberOfPages );
	}

	HRESULT Fire_onSaveComplete( int saveId, int resultCode )
	{
		return invoke( 3, saveId, resultCode );
	}

	HRESULT Fire_onSelectedImageChanged( int index )
	{
		return invoke( 4, index );
	}

	HRESULT Fire_onImageCountChanged( int count )
	{
		return invoke( 5, count );
	}

	HRESULT Fire_onImageAcquired( int index )
	{
		return invoke( 6, index );
	}

	HRESULT Fire_onDeviceEvent( int event )
	{
		return invoke( 7, event );
	}

	HRESULT Fire_onZoomChanged()
	{
		return invoke( 8 );
	}

	HRESULT Fire_onToolStateChanged( int toolId, bool state )
	{
		return invoke( 9, toolId, state ? 1 : 0 );
	}

	HRESULT Fire_onImagePropertiesChanged( int index )
	{
		return invoke( 10, index );
	}

	HRESULT Fire_onError( int errorCode )
	{
		return invoke( 100, errorCode );
	}
};
